﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace ChinessChess
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            net = new CNetWorks(this);
        }

        CBanCo draw;//ve ban co
        Point startDragPoint = Point.Empty;
        Point chessPoint = Point.Empty;
        Point _OriginPoint = Point.Empty;
       
        COCo[] flag =null;// new COCo[90];//so o co tren 1 ban co
        string[] WB = new string[90];
        CImageChess[] chessWhite =null;// new CImageChess[16];
        CImageChess[] chessBlack = null;//new CImageChess[16];//so o co tren 1 ban co
        int nWhite = 0;
        int nBlack = 0;
        public int diff_x;
        public int diff_y;
        int []white=new int [16] {0,1,2,3,4,5,6,7,8,19,25,27,29,31,33,35};
        int[] black = new int[16] { 81, 82, 83, 84, 85, 86, 87, 88, 89, 64, 70, 54, 56, 58, 60, 62 };
        ChessColor player = ChessColor.Default;
        ChessColor me = ChessColor.Default;
        bool opposite = false;
        bool pausegame = false;
        //Biến kiểm tra xem có được phép ăn hay không
        bool eated = false;
        Size curSize;
      
        public bool Pause
        {
            get { return pausegame; }
            set { pausegame = value; }
        }

        #region Network
        CNetWorks net;
        string mess = "";
        int p = 0;

        public ChessColor Player
        {
            get { return player; }
            set { player = value; }
        }
        #endregion Network

        #region "Ham khao tao quan co va ve chung"
        private void InitChess()
        {
            chessWhite = null;
            chessBlack = null;
            flag =new COCo[90];
            chessWhite = new CImageChess[16];
            chessBlack = new CImageChess[16];//so o co tren 1 ban co
            nWhite = 0;
            nBlack = 0;
            Region rg = draw.REGION;
            int d = 0;
            int c = 0;
            for (int i = 0; i < 90; i++)
            {
                WB[i] = "";
                flag[i] = new COCo();
                c = (i) % 9;
                d = (i) / 9;
                flag[i].Dong = d;
                flag[i].Cot = c;
                int vt = 0;
                flag[i].State = false;
                flag[i].Color = ChessColor.Default;
                flag[i].Type = ChessType.Default;
                flag[i].Index =-1;
                flag[i].strName ="";
                if (white.Contains(i))
                {
                    String strName = "W";
                    flag[i].State = true;
                    flag[i].Color = ChessColor.white;
                    flag[i].Type = ChessDraw(i, ref vt,ref strName);
                    flag[i].Index = nWhite;
                    flag[i].strName = strName;

                    //quan co mau trang
                    chessWhite[this.nWhite] = new CImageChess();
                    chessWhite[this.nWhite].Vt = i;
                    chessWhite[this.nWhite].Dong = d;
                    chessWhite[this.nWhite].Cot = c;
                    chessWhite[this.nWhite].strName = strName;
                    chessWhite[this.nWhite].Color = ChessColor.white;
                    chessWhite[this.nWhite].Type = ChessDraw(i, ref vt, ref strName);
                    chessWhite[this.nWhite].Index = nWhite;
                    chessWhite[this.nWhite].DrawChess(this.ImageWhite.Images[vt], this, rg);
                    chessWhite[this.nWhite].MouseDown += new MouseEventHandler(Chess_MouseDown);
                    chessWhite[this.nWhite].MouseMove += new MouseEventHandler(Chess_MouseMove);
                    chessWhite[this.nWhite].MouseUp += new MouseEventHandler(Chess_MouseUp);
                    this.nWhite++;
                    
                }
                if (black.Contains(i))
                {
                    String strName = "B";
                    flag[i].State = true;
                    flag[i].Color = ChessColor.black;
                    flag[i].Type = ChessDraw(i, ref vt,ref strName);
                    flag[i].strName = strName;
                    flag[i].Index = nBlack;//luu vi tri quan co

                   //Quan co mau den
                    chessBlack[this.nBlack] = new CImageChess();
                    chessBlack[this.nBlack].Vt = i;
                    chessBlack[this.nBlack].Dong = d;
                    chessBlack[this.nBlack].Cot = c;
                    chessBlack[this.nBlack].strName = strName;
                    chessBlack[this.nBlack].Color = ChessColor.black;
                    chessBlack[this.nBlack].Type = ChessDraw(i, ref vt, ref strName);
                    chessBlack[this.nBlack].Index = nBlack;
                    chessBlack[this.nBlack].DrawChess(this.imageBlack.Images[vt], this, rg);
                    chessBlack[this.nBlack].MouseDown += new MouseEventHandler(Chess_MouseDown);
                    chessBlack[this.nBlack].MouseMove += new MouseEventHandler(Chess_MouseMove);
                    chessBlack[this.nBlack].MouseUp += new MouseEventHandler(Chess_MouseUp);
                    this.nBlack++;
                }
                
                
            }

        }

        private ChessType ChessDraw(int index, ref int vt,ref String strName)
        {
            switch (index)
            {
                case 4:
                case 85:
                    {
                        strName = "Q" + strName;
                        vt = 0;
                        return ChessType.CQTuong;
                    }
                case 0:
                case 81:
                case 89:
                case 8:
                    {
                        vt = 3;
                        strName = "Xe" + strName + "_" + index.ToString();
                        return ChessType.CXe;
                        //break;
                    }
                case 1:
                case 7:
                case 82:
                case 88:
                    {
                        vt = 5;
                        strName = "Ma" + strName + "_" + index.ToString();
                        return ChessType.CMa;
                        //break;
                    }
                case 2:
                case 6:
                case 83:
                case 87:
                    {
                        vt = 2;
                        strName = "Tuong" + strName + "_" + index.ToString();
                        return ChessType.CTuong;
                        //break;
                    }
                case 3:
                case 5:
                case 84:
                case 86:
                    {
                        vt = 1;
                        strName = "Si" + strName + "_" + index.ToString();
                        return ChessType.CSi;
                        //break;
                    }
                case 19:
                case 25:
                case 64:
                case 70:
                    {
                        vt = 4;
                        strName = "Phao" + strName + "_" + index.ToString();
                        return ChessType.CPhao;
                        //break;
                    }
                case 27:
                case 29:
                case 31:
                case 35:
                case 33:
                case 54:
                case 56:
                case 58:
                case 60:
                case 62:
                    {
                        vt = 6;
                        strName = "Tot" + strName + "_" + index.ToString();
                        return ChessType.CTot;
                        //break;
                    }
            }
            return ChessType.Default;
        }
       
      
        //truyen ten quan co tra ve vi tri no dang o tran ban co
        private int IndexChess(String strName) {
            int vt = -1;
            for (int i = 3; i <= 86; i++) {
                String str = flag[i].strName;
                if (str.ToLower() == strName.ToLower()) {
                    return i;
                }
            }
           return vt;
        }
        #endregion
    

        #region "Cac su kien khi bam vao quan co"
        private void Chess_MouseDown(object sender, MouseEventArgs e){
            if (e.Button == MouseButtons.Left){
                CImageChess oco = (CImageChess)sender;
                oco.BringToFront();
                startDragPoint = e.Location;
                chessPoint = oco.Location;
              
                int mX=Program.beginX + oco.Cot*Program.kc;
                int mY = Program.beginY + oco.Dong * Program.kc;
                _OriginPoint = new Point(mX,mY);
                
            }
            else {
                return;
            }
        }

        private void Chess_MouseMove(object sender, MouseEventArgs e)
        {
            CImageChess oco = (CImageChess)sender;
            if (e.Button == MouseButtons.Left && oco.Color==player)
            {
                oco.Location = new Point(oco.Left + e.X - startDragPoint.X, oco.Top + e.Y - startDragPoint.Y);
            }
            else
                return;
        }

        private void Chess_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                return;
            CImageChess cControl = (CImageChess)sender;

            //Tranh truong hop chua ket noi ma choi.
            //if (net.Connection == StateConnection.Breaken || player == ChessColor.Default)
            //{
            //    // cControl.Location = chessPoint;
            //    //return;
            //}

            int m_X1 = cControl.Location.X;
            int m_Y1 = cControl.Location.Y;
            draw.SnapToPoint(ref m_X1, ref m_Y1);
            int m_X2 = m_X1;
            int m_Y2 = m_Y1;

            Point newpoint = new Point(m_X2, m_Y2);
            
            if (newpoint == _OriginPoint || draw.CheckPoint(newpoint) == false)
            {
                cControl.Location = chessPoint;
                return;
            }

           // player = cControl.Color;
            
            int indexNew = draw.index(newpoint);
            int indexOld = draw.index(_OriginPoint);
            #region Khi 2 Tướng đối mặt nhau
            int bGIndex =IndexChess("QB");//vi tri cua tuong den dang nam tren ban co
            int wGIndex = IndexChess("QW");//vi tri cua tuong trang dang o tren ban co
            #endregion
            //
            
            Boolean opptions = CGame.CheckQTuong(flag, wGIndex, bGIndex, indexOld);
            if (opptions)
            {
                opptions = CGame.CheckNuocDi(flag, indexNew, bGIndex);
                if (!opptions)
                {
                    cControl.Location = this.chessPoint;
                    MessageBox.Show(CMessage.strDoiMatTuong, "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            int color = (int)cControl.Color;
            Checked move = CheckMoveValid(cControl.Index, indexNew, indexOld, newpoint, _OriginPoint,(int)player);
            if (move != Checked.MoveAndEated)
            {
                cControl.Location = chessPoint;
                return;
            }
            else
            {
                switch (player)
                {
                    case ChessColor.black://Black
                        {
                            if (cControl.Type == ChessType.CQTuong){
                                opposite = CGame.CheckQTuong(flag, wGIndex, indexNew);
                                if (opposite)
                                {
                                    MessageBox.Show(CMessage.strDoiMatTuong, "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                    cControl.Location = chessPoint;
                                    return;
                                }
                               
                            }
                            ///
                            player = ChessColor.Default;
                            Process(cControl.Index, indexNew, indexOld, newpoint, _OriginPoint, color);
                            //
                            if (KiemTraChieuTuong(ChessColor.black, wGIndex))
                            {
                                Boolean anquan = anQuan(flag, cControl.Color, indexNew);

                               // if (anquan)
                               // {
                                    MessageBox.Show(CMessage.strChieuTuong, "",
                                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                    lblStatus.Text = "Đến lượt trắng";
                                    player = ChessColor.white;
                               // }
                                return;
                            }
                            Point oldPoint = new Point(_OriginPoint.X - 20, _OriginPoint.Y - 20);
                            //
                            //if (KiemTraChieuTuong(ChessColor.white,bGIndex))
                            //{
                            //    MessageBox.Show("Dang chieu tuong ko di duoc quan nay", "",
                            //        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            //    UndoGame(cControl, indexNew, indexOld, oldPoint);
                            //    player = ChessColor.black;
                            //    return;
                            //}
                            
                             net.sendPacket(indexNew + "," + indexOld + ",2," + newpoint.X + "," + newpoint.Y + "," + _OriginPoint.X + "," + _OriginPoint.Y + "," + cControl.Index + "," + color);
                            lblStatus.Text = "Đến lượt trắng";
                            player = ChessColor.white;
                        } break;
                    case ChessColor.white ://White
                        {
                            if (cControl.Type == ChessType.CQTuong){
                                opposite = CGame.CheckQTuong(flag, indexNew, bGIndex);
                                if (opposite)
                                {
                                    MessageBox.Show(CMessage.strDoiMatTuong, "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                    cControl.Location = chessPoint;
                                    return;
                                }
                                
                            }
                            ///
                            player = ChessColor.Default;
                            Process(cControl.Index,indexNew, indexOld, newpoint, _OriginPoint,color);
                            Point oldPoint = new Point(_OriginPoint.X - 20, _OriginPoint.Y - 20);
                            if (KiemTraChieuTuong(ChessColor.white, bGIndex)) //cam di chuyen quan di vi roi vao pham vi chieu tuong
                            {
                                Boolean anquan = anQuan(flag, cControl.Color, indexNew);
                                //if (anquan)
                                //{
                                    MessageBox.Show(CMessage.strChieuTuong, "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                    lblStatus.Text = "Đến lượt đen";
                                    player = ChessColor.black;
                                //}
                                //UndoGame(cControl, indexNew, indexOld, _OriginPoint);
                                return;
                            }

                            //if (KiemTraChieuTuong(ChessColor.black, wGIndex)){
                            //    MessageBox.Show("Dang chieu tuong ko di duoc quan nay", "",
                            //        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            //    UndoGame(cControl, indexNew, indexOld, oldPoint);
                            //    player = ChessColor.white;
                            //    return;
                            //}
                            net.sendPacket(indexNew + "," + indexOld + ",1," + newpoint.X + "," + newpoint.Y + "," + _OriginPoint.X + "," + _OriginPoint.Y + "," + cControl.Index + "," + color);
                            lblStatus.Text = "Đến lượt đen";
                            player = ChessColor.black;
                        } break;
                    default:
                        cControl.Location = chessPoint;
                        break;
                }
                if (HetCo(ChessColor.white) == false) {
                    MessageBox.Show("Het co trang thua", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    player = ChessColor.Default;
                    btnServer.Enabled = true;
                    return;
                }
                if (HetCo(ChessColor.black) == false)
                {
                    MessageBox.Show("Het co den thua", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    player = ChessColor.Default;
                    btnServer.Enabled = true;
                    return;
                }
            }
           
            this.Cursor = Cursors.Default;

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
          
        }

        private void Form1_MouseEnter(object sender, EventArgs e)
        {

        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
          
            if (e.Button == MouseButtons.Left){
             
            }
            else { 
            }
            
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {

        }
        #endregion

        private void Form1_Load(object sender, EventArgs e)
        {
            Graphics dc = this.CreateGraphics();
            dc.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            draw = new CBanCo(dc);
            InitChess();
            Random rnd = new Random();
            p = rnd.Next(0, 2);
            if (p == 1)
            {
                player = ChessColor.black;
            }
            else
            {
                player = ChessColor.white;
            }
            Setlable(p);
         
            //ham cho dong ho nhay len theo tung giay
            timer1.Enabled = true;
            timer1.Interval = 1000;
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            draw = new CBanCo(e.Graphics);
            draw.DrawChessBoard();
           
        }

        #region"cac ham xu ly"

        private Boolean HetCo(ChessColor color) {
            Boolean isCheck = true;
            CImageChess[] chess;
            if (color == ChessColor.white)
            {
                chess = this.chessWhite;
            }
            else {
                chess = chessBlack;
            }
            for (int i = 0; i < 16; i++) {
                if (chess[i].State == false && chess[i].Type == ChessType.CQTuong) {
                    return false;
                }
            }
            return isCheck;
        }

        //Kiem tra nuoc di cua quan co khi bi chieu tuong
        public Boolean checkNuocDi(COCo []flag,ChessColor color,int indexNew,int gIndex/*vi tri cua quan truong*/) {
            Boolean isCheck = false;
            CImageChess[] chess = null;
            if (color == ChessColor.black)
            {
                chess = chessWhite;
            }
            else
            {
                chess = chessBlack;
            }
            if (flag[indexNew].Dong == flag[gIndex].Dong) {
                int index = gIndex;

                for (int i = 0; i < 16; i++) { 
                    
                }
            }
            else
            if (flag[indexNew].Cot == flag[gIndex].Cot)
                {

                }

            return isCheck;
        }

        private Boolean Xe(ChessColor color,int newIndex,int gIndex) {
            Boolean isCheck = false;
            CQuanCo quanco;
            if (flag[newIndex].Dong == flag[gIndex].Dong)
            {
                int d = gIndex;
                quanco = new CQTuong(flag,gIndex-9,gIndex,flag[gIndex].Color);
                if (quanco.CheckIndex()) {
                    return true;
                }
                int index = gIndex;
                if (newIndex < gIndex) {
                    d = gIndex;
                    switch (color) {
                        case ChessColor.white: {
                            d -= 9;//Old
                            index -= 1;//New
                            while (flag[d].Color!=ChessColor.Default) {
                                d -= 9;
                            }
                            if (flag[d].Color == ChessColor.white) {
                                switch (flag[d].Type) {
                                    case ChessType.CSi:
                                        {
                                            quanco = new CSi(flag, index, d, ChessColor.white);
                                            if (quanco.CheckIndex()) {
                                                return true;//co nuoc do
                                            }
                                            break;
                                        }
                                    case ChessType.CTuong:
                                        {
                                            quanco = new CTuong(flag, index, d, ChessColor.white);
                                            if (quanco.CheckIndex() && quanco.CheckPoint())
                                            {
                                                return true;//co nuoc do
                                            }
                                            break;
                                        }
                                }
                            }

                            for (int j = index; j > newIndex; j--)
                            {
                                d = index-9;
                                while (flag[d].Color != ChessColor.Default){
                                    d -= 9;
                                }
                                if (flag[d].Color == ChessColor.white)
                                {
                                    switch (flag[d].Type)
                                    {
                                        case ChessType.CXe:
                                            {
                                                quanco = new CXe(flag, index, d, ChessColor.white);
                                                if (quanco.CheckIndex() && quanco.CheckPoint())
                                                {
                                                    return true;//co nuoc do
                                                }
                                                break;
                                            }
                                        case ChessType.CPhao:
                                            {
                                                quanco = new CPhao(flag, index, d, ChessColor.white);
                                                if (quanco.CheckIndex() && quanco.CheckPoint())
                                                {
                                                    return true;//co nuoc do
                                                }
                                                break;
                                            }
                                    }
                                }
                                int temp = index-1;
                                temp -= 18;
                                if (flag[temp].Type == ChessType.CMa) {
                                    quanco = new CMa(flag, index, temp, flag[temp].Color);
                                    if (quanco.CheckIndex() && quanco.CheckPoint()) {
                                        return true;
                                    }
                                }
                                temp = index - 2;
                                temp -= 9;
                                if (flag[temp].Type == ChessType.CMa)
                                {
                                    quanco = new CMa(flag, index, temp, flag[temp].Color);
                                    if (quanco.CheckIndex() && quanco.CheckPoint())
                                    {
                                        return true;
                                    }
                                }
                                temp = index + 1;
                                temp -= 18;
                                if (flag[temp].Type == ChessType.CMa)
                                {
                                    quanco = new CMa(flag, index, temp, flag[temp].Color);
                                    if (quanco.CheckIndex() && quanco.CheckPoint())
                                    {
                                        return true;
                                    }
                                }
                                temp = index + 2;
                                temp -= 9;
                                if (flag[temp].Type == ChessType.CMa)
                                {
                                    quanco = new CMa(flag, index, temp, flag[temp].Color);
                                    if (quanco.CheckIndex() && quanco.CheckPoint())
                                    {
                                        return true;
                                    }
                                }
                            }
                            break;
                        }
                        case ChessColor.black:
                            {
                                break;
                            }
                    }
                }
                
            }
            else
                if (flag[newIndex].Cot == flag[gIndex].Cot)
                {

                }
            return isCheck;
        }

        public Boolean anQuan(COCo[] flag, ChessColor color, int indexNew)
        {
            Boolean isCheck = false;
            
            CImageChess[] chess = null;
            if (color == ChessColor.black)
            {
                chess = chessWhite;
            }
            else {
                chess =chessBlack;
            }

            for (int i = 0; i < 16; i++)
            {
                int indexOld = chess[i].Vt;
                if (chess[i].State == true)
                {
                    switch (chess[i].Type)
                    {
                        case ChessType.CQTuong://Tướng
                            {
                                CQuanCo qb = new CQTuong(flag, indexNew, indexOld, chess[i].Color);
                                bool checkIndex = qb.CheckIndex();
                                eated = qb.CheckEated(flag[indexNew].Color);
                                if (checkIndex)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }

                            }
                            break;
                        case ChessType.CSi://Sĩ
                            {
                                CQuanCo si = new CSi(flag, indexNew, indexOld, chess[i].Color);
                                bool checkIndex = si.CheckIndex();
                                eated = si.CheckEated(flag[indexNew].Color);
                                if (checkIndex)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        case ChessType.CTuong://Tượng.........................
                            {
                                CQuanCo tuong = new CTuong(flag, indexNew, indexOld, chess[i].Color);
                                bool checkIndex = tuong.CheckIndex();
                                bool checkPoint = tuong.CheckPoint();
                                eated = tuong.CheckEated(flag[indexNew].Color);
                                if (checkIndex && checkPoint)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        case ChessType.CXe://Xe
                            {
                                CQuanCo xe = new CXe(flag, indexNew, indexOld, chess[i].Color);
                                bool ok = xe.CheckPoint();
                                bool checkIndex = xe.CheckIndex();
                                eated = xe.CheckEated(flag[indexNew].Color);
                                if (checkIndex && ok)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        case ChessType.CPhao://Pháo
                            {
                                CQuanCo cannon = new CPhao(flag, indexNew, indexOld, chess[i].Color);
                                bool checkIndex = cannon.CheckIndex();
                                bool ok2 = cannon.CheckPoint();
                                eated = cannon.CheckEated(flag[indexNew].Color);
                                if (checkIndex && ok2)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        case ChessType.CMa://Mã
                            {
                                CQuanCo ma = new CMa(flag, indexNew, indexOld, chess[i].Color);
                                bool checkPoint = ma.CheckPoint();
                                Boolean checkIndex = ma.CheckIndex();
                                eated = ma.CheckEated(flag[indexNew].Color);
                                if (checkIndex && checkPoint)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        case ChessType.CTot://Tốt
                            {
                                CQuanCo tot = new CTot(flag, indexNew, indexOld, chess[i].Color);
                                bool checkPoint = tot.CheckPoint();
                                Boolean checkIndex = tot.CheckIndex();
                                eated = tot.CheckEated(flag[indexNew].Color);
                                if (checkIndex && checkPoint)
                                {
                                    if (eated)
                                    { //neu an quan
                                        return true;
                                    }
                                }
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            return isCheck;
        }

        private Boolean KiemTraChieuTuong(ChessColor color,int gindex/*Vi tri cua quan tuong*/) {
            Boolean isCheck = false;
            foreach (Control ctrl in this.Controls) {
                if (ctrl is CImageChess) {
                    CImageChess chess = (CImageChess)ctrl;
                    if (chess.Color == color) {
                        isCheck = CGame.KiemTraChieuTuong(chess.Type, flag, chess.Vt, gindex);
                        if (isCheck) {
                            return true;
                        }
                    }
                }
            }
            return isCheck;
        }

        private delegate void ProcessDelegate(int nControlIndex, int indexNew, int indexOld, Point newpoint, Point OriginPoint, int color);
        public void Process(int nControlIndex,int indexNew, int indexOld,  Point newpoint, Point OriginPoint,int color)
        {
            CImageChess cControl = new CImageChess();
            if (InvokeRequired)
            {
                Invoke(new ProcessDelegate(Process),nControlIndex, indexNew, indexOld,newpoint, OriginPoint,color);
                return;
            }

            if (color == 1) {
                cControl = chessBlack[nControlIndex];
            }
            else if (color == 2) { 
                cControl=chessWhite[nControlIndex];
            }
            #region if process
            if (draw.CheckPoint(newpoint))
            {
                switch (cControl.Type)
                {
                    case ChessType.CQTuong://Tướng
                        {
                            CQuanCo qb = new CQTuong(flag, indexNew, indexOld, cControl.Color);
                            bool checkIndex = qb.CheckIndex();
                            eated = qb.CheckEated(flag[indexNew].Color);
                            if (checkIndex)
                            {
                                if (flag[indexNew].State == false)
                                {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else
                                {
                                    if (eated)
                                    { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                    {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else
                            {
                                cControl.Location = this.chessPoint;
                            }
                        }
                        break;
                    case ChessType.CSi://Sĩ
                        {
                            CQuanCo si = new CSi(flag,indexNew, indexOld, cControl.Color);
                            bool checkIndex = si.CheckIndex();
                            eated = si.CheckEated(flag[indexNew].Color);
                            if (checkIndex) {
                                if (flag[indexNew].State == false)
                                {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else
                                {
                                    if (eated)
                                    { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                    {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else {
                                cControl.Location = this.chessPoint;
                            }
                        }
                        break;
                    case ChessType.CTuong://Tượng.........................
                        {
                            CQuanCo tuong = new CTuong(flag,indexNew, indexOld, cControl.Color);
                            bool checkIndex = tuong.CheckIndex();
                            bool checkPoint = tuong.CheckPoint();
                            eated = tuong.CheckEated(flag[indexNew].Color);
                            if (checkIndex && checkPoint) 
                            {
                                if (flag[indexNew].State == false)
                                {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else
                                {
                                    if (eated)
                                    { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                    {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else 
                            {
                                cControl.Location = this.chessPoint;
                            }
                        }
                        break;
                    case ChessType.CXe://Xe
                        {
                            CQuanCo xe = new CXe(flag, indexNew, indexOld, cControl.Color);
                            bool ok = xe.CheckPoint();
                            bool checkIndex = xe.CheckIndex();
                            eated = xe.CheckEated(flag[indexNew].Color);
                            if (ok && checkIndex)
                            {
                                if (flag[indexNew].State == false) {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else {
                                    if (eated)
                                    { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                    {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else {
                                cControl.Location = chessPoint;
                            }
                        }
                        break;
                    case ChessType.CPhao://Pháo
                        {
                            CQuanCo cannon = new CPhao(flag, indexNew, indexOld, cControl.Color);
                            bool ok = cannon.CheckIndex();
                            bool ok2 = cannon.CheckPoint();
                            eated = cannon.CheckEated(flag[indexNew].Color);
                            if (ok2)
                            {
                                if (flag[indexNew].State == false)
                                {
                                    if (ok)
                                    {
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                    }
                                    else
                                        cControl.Location = chessPoint;
                                }
                                else
                                {
                                    if (eated)
                                    {
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                        cControl.Location = chessPoint;
                                }
                            }
                            else
                            {
                                cControl.Location = this.chessPoint;
                            }
                        }
                        break;
                    case ChessType.CMa://Mã
                        {
                            CQuanCo ma = new CMa(flag, indexNew, indexOld, cControl.Color);
                            bool checkPoint = ma.CheckPoint();
                            Boolean checkIndex = ma.CheckIndex();
                            eated = ma.CheckEated(flag[indexNew].Color);
                            if (checkPoint && checkIndex)
                            {
                                if (flag[indexNew].State==false) {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else {
                                    if (eated) { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else {
                                cControl.Location = this.chessPoint;
                            }
                        }
                        break;
                    case ChessType.CTot://Tốt
                        {
                            CQuanCo tot = new CTot(flag, indexNew, indexOld, cControl.Color);
                            bool checkPoint = tot.CheckPoint();
                            Boolean checkIndex = tot.CheckIndex();
                            eated = tot.CheckEated(flag[indexNew].Color);
                            if (checkIndex && checkPoint) {
                                if (flag[indexNew].State == false)
                                {
                                    this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, false);
                                }
                                else
                                {
                                    if (eated)
                                    { //neu an quan
                                        this.MoveChess(cControl, new Point(newpoint.X - 20, newpoint.Y - 20), indexNew, indexOld, true);
                                    }
                                    else
                                    {
                                        cControl.Location = this.chessPoint;
                                    }
                                }
                            }
                            else {
                                cControl.Location = chessPoint;
                            }
                        }
                        break;
                    default:
                        break;
                }

            }
            else
                cControl.Location = chessPoint;
            #endregion

        }
       
 
        //Duy chuyển cờ đến vị trí mới
        private delegate void MoveChessDelegate(CImageChess cControl, Point newpoint, int indexNew, int indexOld, bool eated);
        private void MoveChess(CImageChess cControl, Point newpoint, int indexNew, int indexOld, bool eated)
        {
            ///
            if (InvokeRequired)
            {
                Invoke(new MoveChessDelegate(MoveChess), cControl, newpoint, indexNew, indexOld, eated);
                return;
            }
            if (eated)
            {
                int index=flag[indexNew].Index;
                if(index!=-1){
                    CImageChess removeChess = cControl.Color == ChessColor.white ? chessBlack[index] : chessWhite[index];
                    if (cControl.Color == ChessColor.white) {
                        chessBlack[index].State = false;
                        chessBlack[index].Vt = -1;
                    }
                    else {
                        chessWhite[index].State = false;
                        chessWhite[index].Vt =-1;
                    }
                    this.chessEated.Controls.Add(removeChess);
                    this.Controls.Remove(removeChess);
                    movePoint();
                }
            }
               flag[indexNew].Type = cControl.Type;
               flag[indexNew].Color = cControl.Color;
               flag[indexNew].State = true;
               flag[indexNew].Index = cControl.Index;
               flag[indexNew].strName = cControl.strName;
               cControl.Vt = indexNew;
               cControl.Dong = flag[indexNew].Dong;
               cControl.Cot = flag[indexNew].Cot;
               cControl.Location = newpoint;
               flag[indexOld].State = false;
               flag[indexOld].Index = -1;
               flag[indexOld].Color = ChessColor.Default;
               flag[indexOld].Type = ChessType.Default;
               flag[indexOld].strName = "";
               this.Refresh();
               draw.DrawRect(this.CreateGraphics(), new Point(newpoint.X + 20, newpoint.Y + 20));
               return;
        }

        private void movePoint() {
            int x = 0, y = 10;
            int kc = 41;
            int i =0;
            foreach (Control ctrl in this.chessEated.Controls) {
                Point point = new Point(x, y);
                ctrl.Location = point;
                i++;
                if (i % 5 == 0){
                    y += kc;
                    x = 0;
                }
                else{
                    x += kc;
                }
                
            }
        }
        private delegate void NewGameDelegate();

        private void UndoGame(CImageChess cControl, int indexNew, int indexOld,Point Oldpoint)
        {
            flag[indexOld].State = true;
            flag[indexOld].Index = flag[indexNew].Index;
            flag[indexOld].Color = flag[indexNew].Color;
            flag[indexOld].Type = flag[indexNew].Type;
            flag[indexOld].strName = flag[indexNew].strName;

            flag[indexNew].Type = ChessType.Default;
            flag[indexNew].Color =ChessColor.Default;
            flag[indexNew].State = false;
            flag[indexNew].Index =-1;
            flag[indexNew].strName ="";

            cControl.Vt = indexOld;
            cControl.Dong = flag[indexOld].Dong;
            cControl.Cot = flag[indexOld].Cot;
            cControl.Location = Oldpoint;
            this.Refresh();
            draw.DrawRect(this.CreateGraphics(), new Point(Oldpoint.X + 20, Oldpoint.Y + 20));
        }

        public void NewGame()
        {
            pausegame = false;
            if (InvokeRequired)
            {
                Invoke(new NewGameDelegate(NewGame));
                return;
            }

            foreach (Control ctrl in this.Controls) {
               
                if (ctrl is CImageChess) {
                    this.Controls.Remove(ctrl);
                }
            }

            foreach(Control ctrl in this.chessEated.Controls){
                this.chessEated.Controls.Remove(ctrl);
            }

            Graphics dc = this.CreateGraphics();
            dc.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            draw = new CBanCo(dc);
            InitChess();
            Random rnd = new Random();
            p = rnd.Next(0, 2);
            if (p == 1)
            {
                player = ChessColor.black;
            }
            else
            {
                player = ChessColor.white;
            }
            Setlable(p);
        }

        private void Setlable(int t) {
            if (t == 1) {
                lblStatus.Text = "Đen đi trước";
            }
            else{
                lblStatus.Text = "Trắng đi trước";
            }
        }

        private delegate void SetStatusMessageDelegate(string strArg);
        public void SetStatusMessage(string mess)
        {

            this.mess = mess;
            if (InvokeRequired)
            {
                Invoke(new SetStatusMessageDelegate(SetStatusMessage), new object[] { mess });
                return;
            }

            lblStatus.Text = mess;

        }

        private Checked CheckMoveValid(int ncontrolIndex,int indexNew, int indexOld, Point newpoint, Point OriginPoint,int color)
        {
            CImageChess cControl = new CImageChess();
            if (color == 2) {
                cControl = chessWhite[ncontrolIndex];
            }
            else if (color == 1)
            {
                cControl =chessBlack[ncontrolIndex];
            }
            

            bool eated = false;
            bool m = false;
            switch (cControl.Type)
            {
                case ChessType.CQTuong://tướng
                    {
                        CQuanCo general = new CQTuong(flag, indexNew, indexOld, cControl.Color);
                        

                        m = general.CheckIndex();
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    }; //break;
                case ChessType.CSi:
                    {
                        CQuanCo advisor = new CSi(flag,indexNew, indexOld, cControl.Color);
                        
                        m = advisor.CheckIndex();
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    }; //break;
                case ChessType.CTuong:// tượng
                    {
                        CQuanCo elephant = new CTuong (flag, indexNew, indexOld, cControl.Color);
                        
                        m = elephant.CheckIndex();
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    } //break;
                case ChessType.CTot:
                    {
                        CQuanCo chariot = new CTot(flag, indexNew, indexOld, cControl.Color);
                        m = (chariot.CheckPoint() && chariot.CheckIndex());
                        
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    }; //break;
                case ChessType.CPhao:
                    {
                        CQuanCo cannon = new CPhao(flag, indexNew, indexOld, cControl.Color);
                        m = cannon.CheckPoint();
                        eated = cannon.CheckEated(flag[indexNew].Color);
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;

                    }; //break;
                case ChessType.CMa:
                    {
                        CQuanCo horse = new CMa(flag, indexNew, indexOld, cControl.Color);
                        m = (horse.CheckIndex() && horse.CheckPoint());
                        eated = horse.CheckEated(cControl.Color);
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    } //break;
                case ChessType.CXe:
                    {
                        CQuanCo soldier = new CXe (flag, indexNew, indexOld, cControl.Color);
                        m = soldier.CheckPoint();
                        
                        if ((m == true && eated == true) || (m == true && eated == false))
                            return Checked.MoveAndEated;
                        else
                            return Checked.NoMoveable;
                    } //break;
            }
            return Checked.Default;
        }

        #endregion

        private void btnNewGame_Click(object sender, EventArgs e)
        {
            if (net.Connection == StateConnection.Breaken)
            {
                net.Listen();
                pausegame = false;
            }
        }

        private void timerFlash_Tick(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second;
            label2.Text = DateTime.Now.Day + "/" + DateTime.Now.Month + "/" + DateTime.Now.Year;
        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }

        private void hướngDẫnToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewGame();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (net.Connection == StateConnection.Connecting || net.Connection == StateConnection.Breaken)
            {
                net.ConnectTo(txtIP.Text);
               
                pausegame = false;
            }         
        }
    }
}
